#include <cstring>
#include <cctype>
#include <cstdlib>
#include "uvstring.h"

namespace uv {
namespace string {

bool streq(const std::string& str1, const std::string& str2,
        const bool& case_sensitive) {
    if (str1.size() != str2.size()) {
        return false;
    }
    for (std::string::const_iterator it1 = str1.begin(), it2 = str2.begin();
            it1 != str1.end() && it2 != str2.end(); ++it1, ++it2) {
        if ((case_sensitive && *it1 != *it2) ||
                (!case_sensitive && tolower(*it1) != tolower(*it2))) {
            return false;
        }
    }
    return true;
}

bool getBool(const std::string& str, bool& val) {
    const char *ptr = str.c_str();
    if ((ptr[0] == '1' && ptr[1] == '\0') || streq(str, "true", false)) {
        val = true;
        return true;
    }
    if ((ptr[0] == '0' && ptr[1] == '\0') || streq(str, "false", false)) {
        val = false;
        return true;
    }
    return false;
}

bool isNumeric(const std::string& str) {
    const char *ptr = str.c_str();
    const size_t length = str.size();
    size_t i = 0;
    // Allow strings to start with +/-.
    if (length > 1 && (ptr[0] == '+' || ptr[0] == '-')) {
        i=1;
    }
    // Allow strings to start with 0x for hex values.
    if (length > i + 2 && ptr[i] == '0' && tolower(ptr[i+1]) == 'x') {
        i+=2;
    }
    // Allow only digits from here on out. 
    for (; i < length; ++i) {
        if (ptr[i] < '0' || ptr[i] > '9') {
            return false;
        }
    }
    return true;
}

} // namespace string
} // namespace uv
